<template>
  <div class="vector-management">
    <el-card class="vector-list-card">
      <template #header>
          <div class="card-header">
          <div class="header-left">
            <!-- 全局相似度搜索入口（点击弹出相似度搜索对话框） -->
            <el-tooltip content="打开相似度搜索" placement="top">
              <el-button class="similarity-btn" type="primary" round size="large" :icon="Search" @click="openSimilarityDialog">
                相似度搜索
              </el-button>
            </el-tooltip>
          </div>
          <div class="header-right">
            <!-- 搜索输入框 -->
            <el-input v-model="searchKeyword" placeholder="搜索文本内容" style="width: 250px; margin-right: 10px;"
              clearable @input="handleSearch" @clear="handleSearch">
              <template #prefix>
                <el-icon>
                  <Search />
                </el-icon>
              </template>
            </el-input>
            <!-- 重置按钮 -->
            <el-button @click="resetFilters" type="default">
              <el-icon>
                <Refresh />
              </el-icon>
              重置
            </el-button>
          </div>
        </div>
      </template>

      <!-- 向量列表表格 -->
      <el-table :data="getFilteredVectors()" style="width: 100%" v-loading="loading" element-loading-text="加载中..." empty-text="暂无数据">
        <!-- 文本内容列 -->
        <el-table-column prop="text" label="文本内容" min-width="350" show-overflow-tooltip>
          <template #default="{ row }">
            <div class="text-content">
              <el-tooltip :content="row.text" placement="top">
                <span class="text-display">{{ row.text }}</span>
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
                 <!-- 向量维度列 -->
         <el-table-column prop="dimension" label="向量维度" min-width="80" align="center">
          <template #default="{ row }">
            <el-tag type="info">{{ row.dimension || '未知' }}</el-tag>
          </template>
        </el-table-column>
                 <!-- 向量长度列 -->
         <el-table-column prop="vectorLength" label="向量长度" min-width="80" align="center">
           <template #default="{ row }">
             <el-tag type="warning">{{ formatNumber(row.vectorLength) }}</el-tag>
           </template>
         </el-table-column>
                 <!-- 创建时间列 -->
         <el-table-column prop="createdAt" label="创建时间" min-width="120" align="center">
          <template #default="{ row }">
            {{ formatDate(row.createdAt) }}
          </template>
        </el-table-column>
                 <!-- 操作列 -->
         <el-table-column label="操作" min-width="200" align="center">
          <template #default="{ row }">
            <div class="operation-buttons">
              <!-- 查看详情按钮 -->
              <el-button type="text" size="small" @click="viewVector(row)">
                <el-icon>
                  <View />
                </el-icon>
                查看
              </el-button>
              
              <!-- 删除按钮 -->
              <el-button type="text" size="small" @click="deleteVectorHandler(row)" style="color: #f56c6c;">
                <el-icon>
                  <Delete />
                </el-icon>
                删除
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页组件 -->
      <div class="pagination-container">
        <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100]"
          :total="total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
          @current-change="handleCurrentChange" />
      </div>
    </el-card>

    

    <!-- 向量详情对话框 -->
    <el-dialog v-model="showDetailDialog" title="向量详情" width="700px">
      <div class="vector-detail">
        <div class="detail-header">
          <h3>向量信息</h3>
        </div>
        <el-divider />
        <div class="detail-content">
          <div class="detail-item">
            <label>文本内容:</label>
            <div class="text-detail">{{ selectedVectorDetail.text }}</div>
          </div>
          <div class="detail-item">
            <label>向量维度:</label>
            <el-tag type="info">{{ selectedVectorDetail.dimension || '未知' }}</el-tag>
          </div>
                     <div class="detail-item">
             <label>向量长度:</label>
             <el-tag type="warning">{{ formatNumber(selectedVectorDetail.vectorLength) }}</el-tag>
           </div>
          <div class="detail-item">
            <label>创建时间:</label>
            <span>{{ formatDate(selectedVectorDetail.createdAt) }}</span>
          </div>
          <div class="detail-item">
            <label>向量数据:</label>
            <div class="vector-data">
              <el-input v-model="selectedVectorDetail.vectorData" type="textarea" :rows="4" readonly />
            </div>
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 相似度搜索对话框 -->
    <el-dialog v-model="showSimilarityDialog" title="相似度搜索" width="600px">
      <div class="similarity-search">
        <div class="search-header">
          <h4>基于向量进行相似度搜索</h4>
        </div>
        <el-divider />
        <div class="search-content">
          <div class="search-item">
            <label>搜索文本:</label>
            <el-input v-model="similaritySearchText" type="textarea" :rows="3" placeholder="请输入搜索文本" />
          </div>
          <div class="search-item">
            <label>相似度阈值:</label>
            <el-slider v-model="similarityThreshold" :min="0" :max="1" :step="0.01" show-input />
          </div>
          <div class="search-item">
            <label>返回数量:</label>
            <el-input-number v-model="similarityLimit" :min="1" :max="50" />
          </div>
          <div class="search-actions">
            <el-button type="primary" @click="performSimilaritySearch" :loading="searchingSimilarity">搜索</el-button>
          </div>
        </div>
        <el-divider />
        <div class="search-results" v-if="similarityResults.length > 0">
          <h4>搜索结果</h4>
          <el-table :data="similarityResults" style="width: 100%">
            <el-table-column prop="text" label="文本内容" width="300">
              <template #default="{ row }">
                <el-tooltip :content="row.text" placement="top">
                  <span class="result-text">{{ row.text }}</span>
                </el-tooltip>
              </template>
            </el-table-column>
            <el-table-column prop="similarity" label="相似度" width="120">
              <template #default="{ row }">
                <el-tag :type="getSimilarityTagType(row.similarity)">
                  {{ (row.similarity * 100).toFixed(2) }}%
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Search, View, Edit, Delete, Message, Check, Close, Refresh
} from '@element-plus/icons-vue'
import {
  getVectorList,
  getVectorDetail,
  generateEmbedding,
  deleteVector,
  batchGenerateEmbedding,
  searchVectorSimilarity
} from '@/api/vector'

// ==================== 响应式数据定义 ====================
const loading = ref(false)
// 生成与批量生成功能已移除
const searchingSimilarity = ref(false)
// 对话框已移除
const showDetailDialog = ref(false)
const showSimilarityDialog = ref(false)
const vectorList = ref([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const searchKeyword = ref('')
// 相关表单已移除
const selectedVectorDetail = ref()
const similaritySearchText = ref('')
const similarityThreshold = ref(0.2)
const similarityLimit = ref(10)
const similarityResults = ref([])
let searchTimer = null

// 表单验证已移除

// ==================== 工具函数 ====================
// 格式化数值（用于向量长度等）
const formatNumber = (num) => {
  if (num === null || num === undefined) return '未知'
  if (typeof num === 'string') {
    num = parseFloat(num)
    if (isNaN(num)) return '未知'
  }
  return num.toFixed(2)
}

const formatDate = (dateStr) => {
  try {
    return new Date(dateStr).toLocaleString('zh-CN')
  } catch (e) {
    return dateStr
  }
}

const getSimilarityTagType = (similarity) => {
  if (similarity >= 0.8) return 'success'
  if (similarity >= 0.6) return 'warning'
  return 'info'
}

// ==================== 数据加载函数 ====================
const loadVectors = async () => {
  loading.value = true
  try {
    // 构建搜索参数
    const searchParams = {
      page: currentPage.value,
      pageSize: pageSize.value
    }
    
    // 添加搜索关键词
    if (searchKeyword.value) {
      searchParams.keyword = searchKeyword.value
    }
    
    const res = await getVectorList(searchParams)
    console.log('向量列表数据:', res)
    
    if (res && (res.code === 200 || res.Code === 200)) {
      const data = res.data || {}
      vectorList.value = data.vectorList || []
      total.value = data.totalCount || vectorList.value.length || 0
    } else if (res && Array.isArray(res.data)) {
      // 兼容旧结构
      vectorList.value = res.data
      total.value = res.total || vectorList.value.length || 0
    } else {
      vectorList.value = []
      total.value = 0
    }
  } catch (error) {
    console.error('加载向量列表失败:', error)
    console.error('错误详情:', error.response?.data)
    
    vectorList.value = []
    total.value = 0
    ElMessage.error('加载向量列表失败，请稍后重试')
  }
  loading.value = false
}

// ==================== 搜索和过滤功能 ====================
const handleSearch = () => {
  if (searchTimer) {
    clearTimeout(searchTimer)
  }
  searchTimer = setTimeout(() => {
    loadVectors()
  }, 300)
}

const resetFilters = () => {
  searchKeyword.value = ''
  loadVectors()
}

const getFilteredVectors = () => {
  let filtered = vectorList.value

  // 关键词过滤
  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase()
    filtered = filtered.filter(vector =>
      (vector.text && vector.text.toLowerCase().includes(keyword))
    )
  }

  // 相似度阈值筛选（当列表项包含 similarity 字段时生效）
  if (filtered.length && Object.prototype.hasOwnProperty.call(filtered[0] || {}, 'similarity')) {
    filtered = filtered.filter(v => (v.similarity ?? 1) >= similarityThreshold.value)
  }

  return filtered
}

// ==================== 事件处理函数 ====================
const viewVector = async (vector) => {
  try {
    const res = await getVectorDetail(vector.id)
    selectedVectorDetail.value = res.data || { ...vector }
    showDetailDialog.value = true
  } catch (e) {
    console.error('获取向量详情失败:', e)
    selectedVectorDetail.value = { ...vector }
    showDetailDialog.value = true
  }
}

const searchSimilarity = (vector) => {
  similaritySearchText.value = vector.text
  showSimilarityDialog.value = true
}

const openSimilarityDialog = () => {
  // 打开全局相似度搜索对话框（不带预填文本）
  similaritySearchText.value = ''
  showSimilarityDialog.value = true
}

const deleteVectorHandler = async (vector) => {
  try {
    await ElMessageBox.confirm(`确定要删除向量 "${vector.text.substring(0, 20)}..." 吗？`, '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    await deleteVector(vector.id)
    
    ElMessage.success('删除成功')
    loadVectors()
  } catch (e) {
    if (e !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

// 已移除生成与批量生成的处理函数

const performSimilaritySearch = async () => {
  if (!similaritySearchText.value) {
    ElMessage.warning('请输入搜索文本')
    return
  }
  
  searchingSimilarity.value = true
  
  try {
    const res = await searchVectorSimilarity({
      text: similaritySearchText.value,
      threshold: similarityThreshold.value,
      limit: similarityLimit.value
    })
    // 兼容多种返回结构：{code, data:{ data:[] }} 或 {code, data:[]} 或直接 []
    const payload = res?.data ?? res
    const rawList = Array.isArray(payload)
      ? payload
      : (payload?.Data ?? payload?.data ?? payload?.results ?? payload?.items ?? [])
    const list = Array.isArray(rawList) ? rawList : []
    // 规范字段为小写，便于表格显示
    similarityResults.value = list.map(item => ({
      text: item.text ?? item.Text ?? item.content ?? item.Content ?? '',
      similarity: item.similarity ?? item.Similarity ?? item.score ?? 0
    }))
    ElMessage.success(`搜索完成，共 ${similarityResults.value.length} 条`) 
  } catch (error) {
    console.error('相似度搜索失败:', error)
    ElMessage.error('相似度搜索失败')
  } finally {
    searchingSimilarity.value = false
  }
}

const handleSizeChange = (newSize) => {
  pageSize.value = newSize
  currentPage.value = 1
  loadVectors()
}

const handleCurrentChange = (newPage) => {
  currentPage.value = newPage
  loadVectors()
}

onMounted(() => {
  loadVectors()
})

onUnmounted(() => {
  if (searchTimer) {
    clearTimeout(searchTimer)
  }
})
</script>

<style scoped>
.vector-management {
  padding: 24px;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  min-height: 100vh;
}

.vector-list-card {
  margin-bottom: 24px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  overflow: hidden;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px;
  border-bottom: 1px solid rgba(102, 126, 234, 0.1);
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
}

.header-left {
  display: flex;
  gap: 16px;
  align-items: center;
}

.header-left .el-button.is-plain {
  border-radius: 18px;
}

.similarity-btn {
  height: 44px;
  padding: 0 20px;
  font-size: 16px;
  font-weight: 600;
  border-width: 2px;
  border-color: #8ab4ff;
  color: #3b82f6;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.12) 0%, rgba(118, 75, 162, 0.12) 100%);
}

.similarity-btn .el-icon {
  margin-right: 6px;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.text-content {
  font-weight: 600;
  color: #2c3e50;
  font-size: 16px;
}

.text-display {
  display: inline-block;
  max-width: 400px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.operation-buttons {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  justify-content: center;
  min-width: 150px;
}

.operation-buttons .el-button {
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.3s ease;
  border: 1px solid transparent;
}

.operation-buttons .el-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.operation-buttons .el-button .el-icon {
  margin-right: 4px;
  font-size: 14px;
}

.pagination-container {
  margin-top: 24px;
  display: flex;
  justify-content: center;
  padding: 20px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.vector-detail {
  padding: 24px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.detail-header {
  margin-bottom: 24px;
  padding: 20px;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
  border-radius: 12px;
  border: 1px solid rgba(102, 126, 234, 0.1);
}

.detail-header h3 {
  margin: 0 0 12px 0;
  color: #2c3e50;
  font-size: 20px;
  font-weight: 600;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.detail-content {
  margin-top: 24px;
}

.detail-item {
  display: flex;
  align-items: flex-start;
  margin-bottom: 20px;
  padding: 16px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 8px;
  border: 1px solid rgba(102, 126, 234, 0.1);
  transition: all 0.3s ease;
}

.detail-item:hover {
  background: rgba(102, 126, 234, 0.05);
  transform: translateX(4px);
}

.detail-item label {
  width: 120px;
  font-weight: 600;
  color: #2c3e50;
  flex-shrink: 0;
}

.detail-item span {
  color: #34495e;
  font-weight: 500;
}

.text-detail {
  color: #34495e;
  line-height: 1.8;
  white-space: pre-wrap;
  background: rgba(102, 126, 234, 0.05);
  padding: 12px;
  border-radius: 6px;
  border: 1px solid rgba(102, 126, 234, 0.1);
}

.vector-data {
  flex: 1;
  background: rgba(102, 126, 234, 0.05);
  padding: 12px;
  border-radius: 6px;
  border: 1px solid rgba(102, 126, 234, 0.1);
  font-family: 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.4;
  max-height: 200px;
  overflow-y: auto;
}

.similarity-search {
  padding: 24px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.search-header h4 {
  margin: 0 0 16px 0;
  color: #2c3e50;
  font-size: 18px;
  font-weight: 600;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.search-content {
  margin-top: 24px;
}

.search-item {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  padding: 16px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 8px;
  border: 1px solid rgba(102, 126, 234, 0.1);
}

.search-item label {
  width: 140px;
  font-weight: 600;
  color: #2c3e50;
  flex-shrink: 0;
}

.search-item .el-input,
.search-item .el-slider {
  flex: 1;
}

.search-item .el-input {
  border-radius: 6px;
  border: 1px solid #e1e8ed;
  transition: all 0.3s ease;
}

.search-item .el-input:focus-within {
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}

.search-actions {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

.search-actions .el-button {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  border-radius: 8px;
  padding: 12px 24px;
  font-weight: 500;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}

.search-actions .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}

.search-results {
  margin-top: 24px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 12px;
  border: 1px solid rgba(102, 126, 234, 0.1);
}

.search-results h4 {
  margin: 0 0 16px 0;
  color: #2c3e50;
  font-size: 16px;
  font-weight: 600;
}

.result-text {
  display: inline-block;
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #34495e;
  font-weight: 500;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 16px 24px;
  border-top: 1px solid #f0f2f5;
}

/* 表格样式 */
:deep(.el-table) {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  max-width: 100%;
}

:deep(.el-table th) {
  background: #f8fafc !important;
  color: #374151 !important;
  font-weight: 600;
  border: none;
  border-bottom: 2px solid #e5e7eb;
  padding: 16px 12px;
  font-size: 14px;
}

:deep(.el-table td) {
  border-bottom: 1px solid #f0f2f5;
  padding: 16px 12px;
  transition: all 0.3s ease;
}

:deep(.el-table tr:hover td) {
  background: #f9fafb;
  transform: none;
}

/* 标签样式 */
:deep(.el-tag) {
  border-radius: 6px;
  font-weight: 500;
  padding: 4px 8px;
}

:deep(.el-tag--info) {
  background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%);
  color: white;
  border: none;
}

/* 对话框样式 */
:deep(.el-dialog) {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);
}

:deep(.el-dialog__header) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px 24px;
}

:deep(.el-dialog__title) {
  color: white;
  font-weight: 600;
}

:deep(.el-dialog__body) {
  padding: 24px;
}

/* 动画效果 */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.vector-list-card,
.vector-detail,
.similarity-search,
.pagination-container,
:deep(.el-table) {
  animation: fadeInUp 0.6s ease-out;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .vector-management {
    padding: 16px;
  }
  
  .card-header {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
  }
  
  .header-left,
  .header-right {
    width: 100%;
    justify-content: space-between;
  }
  
  .operation-buttons {
    gap: 4px;
    min-width: auto;
    flex-direction: column;
  }
  
  .operation-buttons .el-button {
    padding: 4px 8px;
    font-size: 11px;
    width: 100%;
  }
  
  /* 确保表格在小屏幕上可以水平滚动 */
  :deep(.el-table) {
    overflow-x: auto;
  }
  
  .search-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  
  .search-item label {
    width: 100%;
  }
}
</style>
